package com.mpsc.api.unit;

import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

public class FileUtil {

    public static void main(String[] args) throws Exception {
       String ss ="672823";
        Set<Integer> set = new TreeSet<>();
       for(int i = 0;i < ss.length();i++){
           set.add(Integer.parseInt(ss.charAt(i)+""));
       }
       StringBuilder s = new StringBuilder();
       set.forEach(o->s.append(o));
        System.out.println(s.toString());
    }
    public static int getDecimal(String number) {
        int res = 0;
        for (char ch : number.toCharArray()) {
            res = res * BASE + map.get(ch);
        }
        return res;
    }
    private final static int BASE = 16;
    private static Map<Character, Integer> map = new HashMap<Character, Integer>()
    {{
        put('0', 0);
        put('1', 1);
        put('2', 2);
        put('3', 3);
        put('4', 4);
        put('5', 5);
        put('6', 6);
        put('7', 7);
        put('8', 8);
        put('9', 9);
        put('A', 10);
        put('B', 11);
        put('C', 12);
        put('D', 13);
        put('E', 14);
        put('F', 15);
        put('a', 10);
        put('b', 11);
        put('c', 12);
        put('d', 13);
        put('e', 14);
        put('f', 15);
    }};
    /**
     * 创建文件
     *
     * @param filePath 文件的绝对路径
     */
    public static void createFile(String filePath) {
        File file = new File(filePath);
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 创建相应的文件夹
     *
     * @param path 文件夹的路劲
     */
    public static void createFilePath(String path) {
        String pathString = "";
        String dir[];
        dir = path.replace('\\', '/').split("/");
        for (int i = 1; i < dir.length; i++) {
            File subFile = new File(pathString + "/" + dir[i]);
            if (subFile.exists() == false)
                subFile.mkdir();
            pathString += "/" + dir[i];
        }
    }

    /**
     * 将一个文件夹下的图片复制到另外一个文件夹下
     *
     * @param oldPath 图片原路径
     * @param newPath 图片新路径
     */
    public static void copyFolder(String oldPath, String newPath) throws Exception {
        try {
            File newFile = new File(newPath);
            if (!newFile.exists()) {
                (new File(newPath)).mkdirs(); // 如果文件夹不存在 则建立新文件夹
            }
            File oldFile = new File(oldPath);
            String[] file = oldFile.list();
            File temp = null;
            for (int i = 0; i < file.length; i++) {
                if (oldPath.endsWith(File.separator)) {
                    temp = new File(oldPath + file[i]);
                } else {
                    temp = new File(oldPath + File.separator + file[i]);
                }

                if (temp.isFile()) {
                    String fileName = newPath + "/" + (temp.getName());
                    File testFile = new File(fileName);
                    if (!testFile.exists()) {
                        FileInputStream input = new FileInputStream(temp);
                        FileOutputStream output = new FileOutputStream(fileName);
                        byte[] b = new byte[1024 * 5];
                        int len;
                        while ((len = input.read(b)) != -1) {
                            output.write(b, 0, len);
                        }
                        output.flush();
                        output.close();
                        input.close();
                    }
                }
                if (temp.isDirectory()) {
                    copyFolder(oldPath + "/" + file[i], newPath + "/" + file[i]);
                }
            }
        } catch (Exception e) {
            System.out.println("复制整个文件夹内容操作出错");
            e.printStackTrace();
            throw e;
        }
    }

    /**
     * 删除文件夹以及文件夹下的内容
     *
     * @param fileRoot 删除的文件或者文件夹
     * @return boolean
     */
    public static Boolean deleteFile(File fileRoot) {
        //判断文件不为null或文件目录存在
        if (fileRoot == null || !fileRoot.exists()) {
            System.out.println("文件删除失败,请检查文件是否存在以及文件路径是否正确");
            return false;
        }
        if (fileRoot.isFile()) {
            fileRoot.delete();
            return true;
        }
        //获取目录下子文件
        File[] files = fileRoot.listFiles();
        //遍历该目录下的文件对象
        for (File file : files) {
            //判断子目录是否存在子目录,如果是文件则删除
            if (file.isDirectory()) {
                //递归删除目录下的文件
                deleteFile(file);
            } else {
                //文件删除
                file.delete();
                //打印文件名
                System.out.println("文件名：" + file.getName());
            }
        }
        //文件夹删除
        fileRoot.delete();
        System.out.println("目录名：" + fileRoot.getName());
        return true;
    }

    /**
     * 追加写入文件内容
     *
     * @param filePath 文件路径
     * @param content  写入的内容
     */
    public static void writeFileContent(String filePath, String content) {

        FileWriter fileWriter = null;
        PrintWriter pw = null;
        try {
            fileWriter = new FileWriter(new File(filePath), true);
            pw = new PrintWriter(fileWriter);
            pw.println(content + "\r\n");
            pw.flush();
            fileWriter.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != pw) {
                    pw.close();
                }
                if (null != fileWriter) {
                    fileWriter.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * mmap 实现copy文件
     *
     * @param readFile  读取文件的绝对地址
     * @param writeFile 写文件的地址
     */
    public static void mmap(String readFile, String writeFile) {
        try {
            // 获取文件
            FileChannel readChannel = FileChannel.open(Paths.get(readFile), StandardOpenOption.READ);
            MappedByteBuffer data = readChannel.map(FileChannel.MapMode.READ_ONLY, 0, 1024 * 1024 * 40);
            FileChannel writeChannel = FileChannel.open(Paths.get(writeFile), StandardOpenOption.WRITE, StandardOpenOption.CREATE);
            //数据传输
            writeChannel.write(data);
            readChannel.close();
            writeChannel.close();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    /**
     * sendFile 实现copy文件
     *
     * @param readFile  读取文件的绝对地址
     * @param writeFile 写文件的地址
     */
    public static void sendFile(String readFile, String writeFile) {

        try {
            FileChannel readChannel = FileChannel.open(Paths.get(readFile), StandardOpenOption.READ);
            long len = readChannel.size();
            long position = readChannel.position();
            FileChannel writeChannel = FileChannel.open(Paths.get(writeFile), StandardOpenOption.WRITE, StandardOpenOption.CREATE);
            //数据传输
            //开始发送数据：在Java中使用零拷贝技术调用transferTo方法，这个方法底层使用了零拷贝技术
            // 在Linux系统下 使用transferTo 方法，没有文件大小限制，可以将文件调用一次transferTo方法即可传输完成
            //但是在Windows系统下调用一次transferTo 方法，最多只能发送 8m 的数据，所以需要将文件进行分段传输
            // transferTo 参数介绍：
            //              第一个参数：从文件的哪里开始读取
            //              第二个参数：读取多少字节
            //              第三个参数：将读取的字节,放入需要写入的Channel中
            readChannel.transferTo(position, len, writeChannel);
            readChannel.close();
            writeChannel.close();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    /**
     * sendFile 实现copy文件
     *
     * @param writeFile     写文件的地址
     * @param multipartFile 读取文件的绝对地址
     */
    public static void sendFile(String writeFile, MultipartFile multipartFile) {
        try {
            String originalFilename = multipartFile.getOriginalFilename();
            String[] filename = originalFilename.split("\\.");
            File readFile = File.createTempFile(filename[0], filename[1]);    //注意下面的 特别注意！！！
            multipartFile.transferTo(readFile);
            readFile.deleteOnExit();
            FileInputStream ins = new FileInputStream(readFile);
            FileChannel readChannel = ins.getChannel();
            long len = readChannel.size();
            long position = readChannel.position();
            FileChannel writeChannel = FileChannel.open(Paths.get(writeFile), StandardOpenOption.WRITE, StandardOpenOption.CREATE);
            //数据传输
            //开始发送数据：在Java中使用零拷贝技术调用transferTo方法，这个方法底层使用了零拷贝技术
            // 在Linux系统下 使用transferTo 方法，没有文件大小限制，可以将文件调用一次transferTo方法即可传输完成
            //但是在Windows系统下调用一次transferTo 方法，最多只能发送 8m 的数据，所以需要将文件进行分段传输
            // transferTo 参数介绍：
            //              第一个参数：从文件的哪里开始读取
            //              第二个参数：读取多少字节
            //              第三个参数：将读取的字节,放入需要写入的Channel中
            readChannel.transferTo(position, len, writeChannel);
            readChannel.close();
            writeChannel.close();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
    /**
     * sendFile 实现copy文件
     *
     * @param readFile     写文件的地址
     */
    public static void sendFile(String readFile) {
        try (RandomAccessFile file = new RandomAccessFile(new File(readFile), "r")) {
            // 获取FileChannel
            FileChannel fileChannel = file.getChannel();
            long size = fileChannel.size();
            // 调用map方法进行文件映射，返回MappedByteBuffer
            MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, size);
            byte[] bytes = new byte[(int)size];
            for (int i = 0; i < size; i++) {
                // 读取数据
                bytes[i] = mappedByteBuffer.get();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    

}
